package org.gruposp2p.aula.gwt.client.representation;

import static org.gruposp2p.aula.gwt.client.util.XmlLabelConstants.*;

import java.util.ArrayList;
import java.util.List;
import org.gruposp2p.aula.gwt.client.content.GlassedDialog;
import org.gruposp2p.aula.gwt.client.event.AulaEventBus;
import org.gruposp2p.aula.gwt.client.event.CoursegroupChangeEvent;
import org.gruposp2p.aula.gwt.client.model.Coursegroup;
import org.gruposp2p.aula.gwt.client.model.Link;
import org.restlet.gwt.Callback;
import org.restlet.gwt.Client;
import org.restlet.gwt.data.MediaType;
import org.restlet.gwt.data.Protocol;
import org.restlet.gwt.data.Request;
import org.restlet.gwt.data.Response;
import org.restlet.gwt.data.Status;
import org.restlet.gwt.resource.XmlRepresentation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.Text;
import com.google.gwt.xml.client.XMLParser;

public class CoursegroupRepresentation {
	
	private static CoursegroupRepresentation instance = new CoursegroupRepresentation();
	
	/**
	 * Method that reads the Courses representation
	 * <?xml version="1.0" encoding="UTF-8"?>
	 * <coursegroup>
	 *    <description>descripción grupo 888</description>
	 *    <coursegroupLink name="Nombre grupo 888" id="3" href="http://localhost:8080/rest/coursegroup/3"/>
	 *    <courseLink name="Curso 222" id="1" href="http://localhost:8080/rest/course/1"/>
	 *    <students>
	 *        <studentLink name="name1 mmm" id="101" href="http://localhost:8080/rest/student/101"/>
	 *    </students>
	 * </coursegroup>
	 * 
	 */	
	private Coursegroup getCoursegroup (XmlRepresentation xmlRepresentation) {
		Coursegroup coursegroup = new Coursegroup ();
		final Document xmlDoc = xmlRepresentation.getDocument();
		final Element coursegroupElement = xmlDoc.getDocumentElement();
		XMLParser.removeWhitespace(coursegroupElement);
		NodeList descriptionNodes = coursegroupElement.getElementsByTagName(DESCRIPTION_ELEMENT);
		if (descriptionNodes != null) {
			Element descriptionElement = (Element)descriptionNodes.item(0);
			coursegroup.setDescription(descriptionElement.getFirstChild().getNodeValue());
		}	
		Element coursegroupLinkElement = (Element)coursegroupElement.getElementsByTagName(COURSEGROUPLINK_ELEMENT).item(0);
		Link coursegroupLink = new Link();
		coursegroupLink.setHref(coursegroupLinkElement.getAttribute(HREF_ATTRIBUTE));
		coursegroupLink.setId(coursegroupLinkElement.getAttribute(ID_ATTRIBUTE));
		coursegroupLink.setName(coursegroupLinkElement.getAttribute(NAME_ATTRIBUTE));	
		coursegroup.setLink(coursegroupLink);		
		Element courseLinkElement = (Element)coursegroupElement.getElementsByTagName(COURSELINK_ELEMENT).item(0);
		Link courseLink = new Link();
		courseLink.setHref(courseLinkElement.getAttribute(HREF_ATTRIBUTE));
		courseLink.setId(courseLinkElement.getAttribute(ID_ATTRIBUTE));
		courseLink.setName(courseLinkElement.getAttribute(NAME_ATTRIBUTE));	
		coursegroup.setCourseLink(courseLink);
		NodeList studentsNodes = coursegroupElement.getElementsByTagName(STUDENTS_ELEMENT);
		if (studentsNodes != null) {
			List<Link> studentsLinks = new ArrayList<Link>();
			for (int i= 0; i < studentsNodes.getLength(); i++) {
				Link studentLink = new Link();
 	 		    Element studentElement = (Element)studentsNodes.item(i);
 	 		    if (studentElement != null) {
 	 		    	studentLink.setHref(studentElement.getAttribute(HREF_ATTRIBUTE));
 	 		    	studentLink.setId(studentElement.getAttribute(ID_ATTRIBUTE));
 	 		    	studentLink.setName(studentElement.getAttribute(NAME_ATTRIBUTE));
 	 		    	studentsLinks.add(studentLink);
 	 		    }				
			}
			coursegroup.setStudentsLinks(studentsLinks);
		}
		NodeList subjectsNodes = coursegroupElement.getElementsByTagName(SUBJECT_ELEMENT);
		if (subjectsNodes != null) {
			List<Link> subjectsLinks = new ArrayList<Link>();
			for (int i= 0; i < subjectsNodes.getLength(); i++) {
				Link subjectLink = new Link();
 	 		    Element subjectElement = (Element)subjectsNodes.item(i);
 	 		    if (subjectElement != null) {
 	 		    	subjectLink.setHref(subjectElement.getAttribute(HREF_ATTRIBUTE));
 	 		    	subjectLink.setId(subjectElement.getAttribute(ID_ATTRIBUTE));
 	 		    	subjectLink.setName(subjectElement.getAttribute(NAME_ATTRIBUTE));
 	 		    	subjectsLinks.add(subjectLink);
 	 		    }				
			}
			coursegroup.setSubjectLinks(subjectsLinks);
		}		
		return coursegroup; 
	}
	
	/**
	 * Method that create the Coursegroup representation
	 * <?xml version="1.0" encoding="UTF-8"?>
	 * <coursegroup>
	 *    <description>descripción grupo 888</description>
	 *    <coursegroupLink name="Nombre grupo 888" id="3" href="http://localhost:8080/rest/coursegroup/3"/>
	 *    <courseLink name="Curso 222" id="1" href="http://localhost:8080/rest/course/1"/>
	 *    <students>
	 *        <studentLink name="name1 mmm" id="101" href="http://localhost:8080/rest/student/101"/>
	 *    </students>
	 * </coursegroup>
	 * 
	 */		
	private XmlRepresentation getRepresentation (Coursegroup coursegroup) {
		XmlRepresentation result = null;
	    Document xmlDoc = XMLParser.createDocument();
	    Element coursegroupElement = xmlDoc.createElement(COURSEGROUP_ELEMENT);
	    Element studentsElement = xmlDoc.createElement(STUDENTS_ELEMENT);
	    List<Link> studentsLinks = coursegroup.getStudentsLinks();
	    if (studentsLinks != null) {
		    for (Link link : studentsLinks) {
		    	Element studentElement = xmlDoc.createElement("studentLink");
		    	studentElement.setAttribute(NAME_ATTRIBUTE, link.getName());
		    	studentElement.setAttribute(ID_ATTRIBUTE, link.getId());
		    	studentElement.setAttribute(HREF_ATTRIBUTE, link.getHref());
		    	studentsElement.appendChild(studentElement);
		    }	    	
	    } 
	    coursegroupElement.appendChild(studentsElement); 
    	Element coursegroupDescriptionElement = xmlDoc.createElement(DESCRIPTION_ELEMENT);
    	Text descriptionTxt = xmlDoc.createTextNode(coursegroup.getDescription());
    	coursegroupDescriptionElement.appendChild(descriptionTxt);   	
    	coursegroupElement.appendChild(coursegroupDescriptionElement);
	    result = new XmlRepresentation(MediaType.TEXT_XML, xmlDoc);
	    
	    return result;
	}
	
	public void getCoursegroup (Link coursegroupLink) {
		GlassedDialog.getInstance().showLoadingCoursesDialog();
		final Client client = new Client(Protocol.HTTP);
		client.get(coursegroupLink.getHref(), new Callback() {
			@Override
			public void onEvent(Request request, Response response) {
				CoursegroupChangeEvent coursegroupChangeEvent = new CoursegroupChangeEvent();
				Status status = response.getStatus();
				if (status.getCode() == Status.SUCCESS_OK.getCode()) {
					GWT.log("response.getStatus().getName(): " + response.getStatus().getName(), null); 
					coursegroupChangeEvent.setCoursegroup(
							getCoursegroup(response.getEntityAsXml()));
					AulaEventBus.getInstance().fireEvent(coursegroupChangeEvent);	
					GlassedDialog.getInstance().hideDialog();
				} else {
					GlassedDialog.getInstance().showErrorGettingResource(response.getStatus());
				}
			}}); 
	}
	
	public void putCoursegroup (Coursegroup coursegroup) {
		final Client client = new Client(Protocol.HTTP);
		client.put(coursegroup.getLink().getHref(), getRepresentation(coursegroup), new Callback() {
		@Override
		public void onEvent(Request request, Response response) {
			GWT.log("response.getStatus(): " + response.getStatus(), null);
		}});
	}
		
	public static CoursegroupRepresentation getInstance() {
		return instance;
	}	  

}